﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BankSystem
{
    // 银行类
    public class Bank
    {
        private List<Account> _accounts = new List<Account>();
        public string Name { get; private set; }

        // 构造函数，初始化银行名
        public Bank(string name)
        {
            Name = name;
        }

        // 索引器：通过账号查找账户
        public Account this[string accountNumber]
        {
            get
            {
                foreach (Account account in _accounts)// foreach的用法！
                {
                    if (account.AccountNumber == accountNumber)
                    {
                        return account;
                    }
                }
                return null; // 未找到返回null
            }
        }

        // 添加账户到银行
        public void AddAccount(Account account)
        {
            _accounts.Add(account);
        }
    }

    // 基类：账户
    public class Account
    {
        private string _password;// 账户密码
        protected decimal _balance;// 账户余额

        public string AccountNumber { get; }// 账号，只读！
        public string Owner { get; }// 账户持有人，只读！
        public decimal Balance// 获取余额
        {
            get { return _balance; }
        }

        // 构造函数，初始化账户信息
        public Account(string number, string owner, string pwd, decimal initBalance)
        {
            AccountNumber = number;
            Owner = owner;
            _password = pwd;
            _balance = initBalance;
        }

        // 存款
        public virtual void Deposit(decimal amount)
        {
            if (amount <= 0) throw new ArgumentException("金额必须大于0");
            _balance += amount;
        }

        // 取款（虚方法）
        public virtual bool Withdraw(decimal amount)
        {
            if (amount <= 0) throw new ArgumentException("金额必须大于0");
            if (_balance >= amount)
            {
                _balance -= amount;
                return true;
            }
            return false;
        }

        // 修改密码
        public void ChangePassword(string oldPwd, string newPwd)
        {
            if (oldPwd != _password) throw new Exception("原密码错误");
            _password = newPwd;
        }

        // 重写ToString方法，返回账户信息
        // ToString()方法是System.Object类中的一个虚方法，System.Object类是所有类的基类
        public override string ToString()
        {
            return $"账户类型：普通账户 账号：{AccountNumber} 户主：{Owner} 余额：{Balance:C}";
        }
    }

    // 信用账户子类
    public class CreditAccount : Account
    {
        private decimal _creditLimit;// 信用额度

        public decimal CreditLimit
        {
            get => _creditLimit;
            set => _creditLimit = value > 0 ? value : throw new ArgumentException("信用额度必须大于0");
        }

        // 构造函数，初始化信用账户
        public CreditAccount(string number, string owner, string pwd,
                           decimal initBalance, decimal creditLimit)
                           : base(number, owner, pwd, initBalance)
        {
            CreditLimit = creditLimit;
        }

        // 覆盖取款方法
        public override bool Withdraw(decimal amount)
        {
            if (amount <= 0) throw new ArgumentException("金额必须大于0");

            if (base._balance + _creditLimit >= amount)// 检查余额加上信用额度是否足够
            {
                base._balance -= amount;
                return true;
            }
            return false;
        }

        // 重写ToString方法，返回信用账户信息
        public override string ToString()
        {
            return $"账户类型：信用账户 账号：{AccountNumber} 户主：{Owner} " +
                   $"余额：{Balance:C} 信用额度：{CreditLimit:C}";
        }
    }

    // ATM类
    public class ATM
    {
        private Bank _bank;// 关联的银行对象

        // 构造函数，初始化ATM关联的银行
        public ATM(Bank bank)
        {
            _bank = bank;
        }

        public void Start()
        {
            Console.WriteLine("欢迎使用ATM系统");
            var account = VerifyAccount();

            while (true)
            {
                Console.WriteLine("\n请选择操作：1存款 2取款 3查询余额 4退出");
                switch (Console.ReadLine())
                {
                    case "1":
                        Console.Write("输入存款金额：");
                        account.Deposit(decimal.Parse(Console.ReadLine()));
                        break;
                    case "2":
                        Console.Write("输入取款金额：");
                        Console.WriteLine(account.Withdraw(decimal.Parse(Console.ReadLine()))
                            ? "取款成功" : "余额不足");
                        break;
                    case "3":
                        Console.WriteLine(account);
                        break;
                    case "4": return;
                }
            }
        }

        private Account VerifyAccount()
        {
            Console.Write("输入账号：");
            var account = _bank[Console.ReadLine()];
            Console.Write("输入密码：");
            if (account == null) throw new Exception("账户不存在");
            return account;
        }
    }
    internal class Program
    {
        static void Main(string[] args)
        {
            var bank = new Bank("建设银行");

            // 创建普通账户
            bank.AddAccount(new Account("666666", "张三", "123456", 1000));

            // 创建信用账户
            bank.AddAccount(new CreditAccount("777777", "李四", "654321", 5000, 10000));

            var atm = new ATM(bank);
            atm.Start();
        }
    }
}
